import 'dart:io';
import 'dart:convert';

const host = "127.0.0.1:8000";

// Use a single HttpClient instance to persist cookies
final HttpClient _httpClient = HttpClient();


myFetch(method, uri, body, cb, headers2, errCallback) {
    HttpClient httpClient = _httpClient;
    Future<HttpClientRequest> requestFuture;
    
    // 根据请求方法创建对应的请求
    if (method == 'GET') {
      requestFuture = httpClient.getUrl(uri);
    } else if (method == 'POST') {
      requestFuture = httpClient.postUrl(uri);
    } else {
      // 其他HTTP方法可在此处扩展
      requestFuture = httpClient.openUrl(method, uri);
    }
    
    requestFuture.then((req) {
      // Get CSRF token from cookies
      String? csrfToken;
      List<Cookie> cookies = httpClient.cookies;
      for (Cookie cookie in cookies) {
        if (cookie.name == 'csrftoken') {
          csrfToken = cookie.value;
          break;
        }
      }
      
      // 设置请求头
      Map<String, dynamic> allHeaders = headers2 ?? {};
      
      // Add CSRF token header for non-GET requests
      if (method != 'GET' && csrfToken != null) {
        allHeaders.putIfAbsent('X-CSRFToken', () => csrfToken);
      }
      
      // Apply all headers
      allHeaders.forEach((key, value) {
        req.headers.add(key, value);
      });
      
      // 处理请求体
    if (body != null && method != 'GET') {
      if (headers2?['Content-Type'] == 'application/x-www-form-urlencoded') {
        // 表单数据格式处理
        String formData = body.entries.map((entry) {
          return '${Uri.encodeComponent(entry.key)}=${Uri.encodeComponent(entry.value)}';
        }).join('&');
        req.write(formData);
      } else {
        // 默认JSON格式处理
        req.write(json.encode(body));
      }
    }
    
    req.close().then((res) {
      var t = res.transform(utf8.decoder);
      t.join().then((tran) {
        print(tran);
        var items = json.decode(tran);
        cb(items);
      });
    });
  }).catchError((e) {
    print(e);
    if (errCallback != null) {
      errCallback(e);
    }
  });
}

getRaw(uri, cb, errCallback) {
  return myFetch('GET', uri, null, cb, null, errCallback);
}

get(url, Map<String, dynamic>? data, cb, errCallback) {
  // Convert all parameter values to strings to avoid Uri construction errors
  final Map<String, String>? params;
  if (data != null) {
    final entries = <MapEntry<String, String>>[];
    data.forEach((key, value) {
      entries.add(MapEntry(key, value?.toString() ?? ''));
    });
    params = Map<String, String>.fromEntries(entries);
  } else {
    params = null;
  }
  var uri = Uri.http(host, url, params);
  return getRaw(uri, cb, errCallback);
}

delete1(url, data, cb, errCallback) {
  var uri = Uri.http(host, url);
  var method = 'DELETE';
  return myFetch(method, uri, data, cb, null, errCallback);
}

post(url, data, cb, errCallback) {
  var uri = Uri.http(host, url);
  var method = 'POST';
  return myFetch(method, uri, data, cb, null, errCallback);
}

put(url, data, cb, errCallback) {
  var method = 'PUT';
  var uri = Uri.http(host, url);
  return myFetch(method, uri, data, cb, null, errCallback);
}

postOrPut(url, data, cb, errCallback) {
  var uri = Uri.http(host, url);
  var method = 'POST';
  if (data.id) {
    method = 'PUT';
  }
  return myFetch(method, uri, data, cb, null, errCallback);
}

postForm(url, data, cb, errCallback) {
  var method = 'POST';
  HttpClient httpClient = new HttpClient();
  return httpClient.getUrl(Uri.parse(url)).then((response) {
    //	  if (response.status >= 200 && response.status < 300) {
    //	  	var r = response.json();
    //  r.then(cb).catch(errCallback);
    //}
    //else{
    // const error = new Error(`HTTP Error ${response.statusText}`);
    // error.status = response.statusText;
    // error.response = response;
    // errCallback(error);
    //}
  }).catchError((e) {
    errCallback(e);
  });
}

contacts(data, cb, errCallback) {
  return get('/rest/Contact/', data, cb, errCallback);
}

usePacks(query, cb, errCallback) {
  var data = {"contact": query};
  return get('/rest/UsePack/', data, cb, errCallback);
}

packItems(query, cb) {
  var data = {"pack": query};
  return get('/rest/PackItem/', data, cb, null);
}

items(query, cb) {
  var data = {"search": query};
  return get('/rest/Item/', data, cb, null);
}

loginIndex(cb) {
  //var uri = Uri.http(host, '/rest/login_index');
  return get('/rest/login_index/', null, cb, null);
}

logout(cb) {
  return get('/rest/logout/', null, cb, null);
}

login(username, password, cb, errCallback) {
  //post form
  var payload = {
    'username': username,
    'password': password,
  };
  var body = payload; //queryString.stringify(payload);
  var uri = Uri.http(host, '/rest/login/');
  return myFetch(
      'POST',
      uri,
      body,
      cb,
      {
        'META': 'CSRF_COOKIE',
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      errCallback);
}

//  checkStatus(response) {
//   if (response.status >= 200 && response.status < 300) {
//     return response;
//   }
//   const error = new Error(`HTTP Error ${response.statusText}`);
//   error.status = response.statusText;
//   error.response = response;
//   throw error;
// }

//  parseJSON(response) {
//   var r = response.json();
//   return r;
// }
sql(cmd, callback) {
  get('/rest/sql/', {"cmd": cmd}, callback, (){});
}
//const Client = {
//  init: (m, callback) => {
//    callback();
//  },
//  sql,
//  getRaw,
//  contacts,
//  items,
//  login_index,
//  login,
//  logout,
//  UsePacks,
//  PackItems,
//  get,put,
//  post,
//  postOrPut,
//  delete1,
//  postForm,
//};
//export default Client;
void main(){
  //sql("select * from parts_item limit 3", (res){
  //  print(res);
  //});
  loginIndex((r){
    print(r);
  });
  login("马红权","333333",(r){
    print(r);
  }, (err) {
    print(err);
  });
  //items("123", (res){
  //  print(res);
  //});
  //var data = {"limit": "2"};
  //contacts(data, (res) {
  //  print(res);
  //}, (err) {
  //  print(err);
  //});
  //usePacks("600", (res){
  //  print(res);
  //}, (){});
  //dio.interceptors..add(CookieManager(CookieJar()))..add(LogInterceptor());
  //HttpClient httpClient = new HttpClient();
  //var uri=Uri.parse(host+"/rest/Contact");
  //HttpClientRequest request = await httpClient.getUrl(uri);
  //HttpClientResponse response = await request.close();
  //String responseBody = await response.transform(utf8.decoder).join();
  //var items=json.decode(responseBody);
  //print(items["total"]);
  //print(items["data"]);
}